package com.linkage.bss.crm.packagemgr.bmo.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.linkage.bss.crm.packagemgr.bmo.IPackageCheckBMO;
import com.linkage.bss.crm.packagemgr.bmo.IPackageManagerBMO;
import com.linkage.bss.crm.packagemgr.dao.IPackageObjDAO;
import com.linkage.bss.crm.packagemgr.model.ActionOrderItem;
import com.linkage.bss.crm.packagemgr.model.ActionParameter;
import com.linkage.bss.crm.packagemgr.model.CheckResult;
import com.linkage.bss.crm.packagemgr.model.OfferRoles;
import com.linkage.bss.crm.packagemgr.model.OfferSpecDto;
import com.linkage.bss.crm.packagemgr.model.Package;
import com.linkage.bss.crm.packagemgr.model.PackageObject;
import com.linkage.bss.crm.packagemgr.model.RoleObj;
import com.linkage.bss.crm.packagemgr.util.Constant;

public class PackageCheckBMOImpl implements IPackageCheckBMO {

	private IPackageObjDAO packageObjDAO;

	private IPackageManagerBMO packageManagerBMO;

	/**
	 * 用于缓存互斥的对象
	 */
	private static List<String> exclusiveObjs = new ArrayList<String>();
	/**
	 * 用于缓存与某对象互斥的对象
	 */
	private static Map<String, List<String>> exclusiveMap = new HashMap<String, List<String>>();

	/**
	 * 用于缓存连带或互斥的销售品规格（key为exclude_或related_加销售品规格）
	 */
	private Map<String, List<String>> offerSpecCache = new HashMap<String, List<String>>();
	/**
	 * 用于缓存销售品角色（key为销售品规格或销售品规格加角色）
	 */
	private Map<String, List<OfferRoles>> offerRolesCache = new HashMap<String, List<OfferRoles>>();
	private Map<String, List<RoleObj>> roleObjCache = new HashMap<String, List<RoleObj>>();

	public IPackageObjDAO getPackageObjDAO() {
		return packageObjDAO;
	}

	public void setPackageObjDAO(IPackageObjDAO packageObjDAO) {
		this.packageObjDAO = packageObjDAO;
	}

	public IPackageManagerBMO getPackageManagerBMO() {
		return packageManagerBMO;
	}

	public void setPackageManagerBMO(IPackageManagerBMO packageManagerBMO) {
		this.packageManagerBMO = packageManagerBMO;
	}

	public CheckResult checkPackageByPackageId(Long packageId) {
		CheckResult checkResult = new CheckResult();
		Package packageInfo = null;
		try {
			packageInfo = packageManagerBMO.getPackageById(packageId);
		} catch (Exception e) {
			checkResult.setResult(false);
			checkResult.setErrMsg("根据包ID：" + packageId + "未查到包信息！\n");
		}
		if (packageInfo != null) {
			checkResult = checkPackageByObj(packageInfo);
		} else {
			checkResult.setResult(false);
			checkResult.setErrMsg("根据包ID：" + packageId + "未查到包信息！\n");
		}
		return checkResult;
	}

	public CheckResult checkPackageByObj(Package packageInfo) {
		//将错误信息保存起来，去除重复
		List<String> errMsgList = new ArrayList<String>();
		CheckResult checkResult = new CheckResult(true);
		StringBuffer errMsg = new StringBuffer();
		StringBuffer promptMsg = new StringBuffer();
		exclusiveObjs.clear();
		exclusiveMap.clear();
		offerSpecCache.clear();
		offerRolesCache.clear();
		roleObjCache.clear();

		List<PackageObject> packageObjList = packageInfo.getPackageObjList();
		List<ActionOrderItem> packActionItems = packageInfo.getActionOrderItemList();

		//校验包对象有效性，同时建立包对象编码与包对象映射关系
		Map<String, PackageObject> packObjMap = new HashMap<String, PackageObject>();
		for (PackageObject packageObj : packageObjList) {
			//校验所有包对象的有效性
			CheckResult objAvailResult = checkPackObjAvailable(packageObj);
			convertCheckResult(objAvailResult, checkResult, errMsg, errMsgList);

			//建立包对象编码与包对象的映射关系
			String objNumber = packageObj.getObjectNumber();
			packObjMap.put(objNumber, packageObj);
		}

		//校验成员数量
		CheckResult memQtyResult = checkPackMemberQty(packActionItems, packObjMap);
		convertCheckResult(memQtyResult, checkResult, errMsg, errMsgList);

		//根据参与对象分组动作条目
		//参与对象有加入时才有互斥，连带
		for (PackageObject packObj : packageObjList) {
			String objNumber = packObj.getObjectNumber();
			String objType = packObj.getObjType();
			if (objType.equals(Constant.OBJ_TYPE_PRODUCT)) {
				//参与对象相关的动作条目
				List<ActionOrderItem> objItems = getObjItems(objNumber, packActionItems);
				//参与对象相关的目标对象
				List<PackageObject> partRelaEffectObjs = getPartRelaEffectObjs(objItems, packObjMap);

				//校验互斥
				CheckResult objExcludeResult = checkPackObjExclusive(partRelaEffectObjs);
				convertCheckResult(objExcludeResult, checkResult, errMsg, errMsgList);

				//校验参与对象的是否有多次订购或多次加入的动作
				CheckResult partItemResult = checkRelaOfferAmount(objItems, packObjMap);
				convertCheckResult(partItemResult, checkResult, errMsg, errMsgList);

				for (ActionOrderItem objItem : objItems) {
					String actionTypeCd = objItem.getActionTypeCd();
					if (actionTypeCd.equals(Constant.ACTION_TYPE_ORDER)) {
						//校验依赖
						CheckResult objRelaResult = checkPackObjRela(objItem, partRelaEffectObjs, packObjMap);
						convertCheckResult(objRelaResult, checkResult, errMsg, errMsgList);

						//校验连带（有订购时，才校验是否有连带）
						CheckResult relaOfferResult = checkRelatedOffer(objItem, objItems, packObjMap);
						convertCheckResult(relaOfferResult, checkResult, errMsg, errMsgList);

					} else if (objItem.getActionTypeCd().equals(Constant.ACTION_TYPE_JOIN)) {
						//校验加入动作是否配置了相应的成员销售品（如果需要配置）
						CheckResult hasConfigedReqOffer = checkHasConfigedReqOffer(objItem, objItems, packActionItems,
										packObjMap);
						convertCheckResult(hasConfigedReqOffer, checkResult, errMsg, errMsgList);
					}
				}

			} else if (objType.equals(Constant.OBJ_TYPE_CUST)) {
				List<ActionOrderItem> objItems = getObjItems(objNumber, packActionItems);
				for (ActionOrderItem objItem : objItems) {
					String efferNumber = objItem.getEffectobjNumber();
					PackageObject effectObj = packObjMap.get(efferNumber);
					//校验组合的成员数量
					CheckResult offerMemberQty = checkOfferMemberQty(effectObj, packActionItems, packObjMap);
					boolean offerMemberQtyResult = convertCheckResult(offerMemberQty, checkResult, errMsg, errMsgList);
					if (offerMemberQtyResult) {
						//客户下订购的销售品没有配置成员时，给出提示
						if (!hasEffectObjJoinedItem(efferNumber, packActionItems)) {
							promptMsg.append("客户下订购的【");
							promptMsg.append(effectObj.getObjectName());
							promptMsg.append("】未配置任何成员加入动作，建议为其添加成员配置！\n");
						}
					}
				}
			}
		}

		checkResult.setErrMsg(errMsg.toString());
		checkResult.setPromptMsg(promptMsg.toString());
		return checkResult;
	}

	private boolean convertCheckResult(CheckResult currResult, CheckResult checkResult, StringBuffer errMsg,
					List<String> errMsgList) {
		boolean flag = currResult.isResult();
		if (!flag) {
			checkResult.setResult(false);
			String errorMsg = currResult.getErrMsg();
			if (!errMsgList.contains(errorMsg)) {
				errMsg.append(errorMsg);
				errMsgList.add(errorMsg);
			}
		}
		return flag;
	}

	//获取参与对象相关的动作条目
	private List<ActionOrderItem> getObjItems(String objNumber, List<ActionOrderItem> packActionItems) {
		List<ActionOrderItem> objItems = new ArrayList<ActionOrderItem>();
		for (ActionOrderItem actionItem : packActionItems) {
			if (actionItem.getPartobjNumber().equals(objNumber)) {
				objItems.add(actionItem);
			}
		}
		return objItems;
	}

	//客户订购的销售品是否有成员加入
	private boolean hasEffectObjJoinedItem(String efferNumber, List<ActionOrderItem> actionItems) {
		boolean flag = false;
		for (ActionOrderItem actionItem : actionItems) {
			String tempEffectObjNum = actionItem.getEffectobjNumber();
			String tempActionType = actionItem.getActionTypeCd();
			if (tempEffectObjNum.equals(efferNumber) && tempActionType.equals(Constant.ACTION_TYPE_JOIN)) {
				flag = true;
				break;
			}
		}
		return flag;
	}

	private boolean isOfferExclude(String offerSpecId, String destOfferSpecId) {
		return packageObjDAO.isOfferExclude(offerSpecId, destOfferSpecId);
	}

	/**
	 * 获取组合销售品的付费方式
	 * @param efferObjNumber
	 * @param packActionItems
	 * @return [参数说明]
	 * 
	 */
	private String getEffectObjFeeType(String efferObjNumber, List<ActionOrderItem> packActionItems,
					Map<String, PackageObject> packObjMap) {
		String feeType = null;
		ActionOrderItem actionItem = null;
		for (ActionOrderItem packActionItem : packActionItems) {
			String tempActionType = packActionItem.getActionTypeCd();
			String tempPartObjNumber = packActionItem.getPartobjNumber();
			PackageObject partObj = packObjMap.get(tempPartObjNumber);
			String partObjType = partObj.getObjType();
			String tempEfferObjNumber = packActionItem.getEffectobjNumber();
			if (tempActionType.equals(Constant.ACTION_TYPE_ORDER) && tempEfferObjNumber.equals(efferObjNumber)
							&& partObjType.equals(Constant.CUST.toString())) {
				actionItem = packActionItem;
				break;
			}

		}
		if (null != actionItem) {
			List<ActionParameter> actionParams = actionItem.getActionItemParameterList();
			if (null != actionParams && actionParams.size() > 0) {
				for (ActionParameter actionParam : actionParams) {
					String paramTypeCd = actionParam.getParameterType();
					if (paramTypeCd.equals(Constant.PARAM_TYPE_FEETYPE)) {
						String paramValue = actionParam.getOptionValue();
						String[] values = paramValue.split("\\|");
						//当只配置了一种付费类型是要做限制
						if (values.length == 1) {
							feeType = values[0];
							break;
						}
					}
				}
			}
		}
		return feeType;
	}

	/**
	 * 产品是否有订购了指定的销售品
	 * @param actionItems
	 * @param packObjMap
	 * @param orderOfferSpecs
	 * @return [参数说明]
	 */
	private boolean hasPartObjConfigedCoreOffer(PackageObject efferObj, List<ActionOrderItem> objItems,
					Map<String, PackageObject> packObjMap, List<OfferSpecDto> orderOfferSpecs, String feeType) {
		boolean flag = false;
		outer: for (ActionOrderItem objItem : objItems) {
			String actionTypeCd = objItem.getActionTypeCd();
			String joinOfferSpecId = efferObj.getObjId();
			if (actionTypeCd.equals(Constant.ACTION_TYPE_ORDER)) {
				String tempEfferObjNumber = objItem.getEffectobjNumber();
				PackageObject tempEffectObj = packObjMap.get(tempEfferObjNumber);
				String tempEffectObjId = tempEffectObj.getObjId();
				//如果订购了组合要求的成员销售品（限制只能选已配置的销售品），校验通过
				for (OfferSpecDto orderOfferSpec : orderOfferSpecs) {
					String orderOfferSpecId = orderOfferSpec.getOfferSpecId().toString();
					if (tempEffectObjId.equals(orderOfferSpecId)) {
						//如果要现在付费类型
						if (feeType != null) {
							String offerFeeType = orderOfferSpec.getFeeType().toString();
							//如果销售品付费类型是预后不限，直接通过
							if (offerFeeType.equals(Constant.FEE_TYPE_NO_LIMIT)
											|| offerFeeType.equals(Constant.FEE_TYPE_NO_LIMIT_DEF_POST)
											|| offerFeeType.equals(Constant.FEE_TYPE_NO_LIMIT_DEF_PRE)) {
								flag = true;
								break outer;
							} else if (offerFeeType.equals(feeType)) { //或者与要求的付费类型一致
								flag = true;
								break outer;
							}
						} else {
							flag = true;
							break outer;
						}
					}
				}
			} else if (actionTypeCd.equals(Constant.ACTION_TYPE_JOIN)) {
				//如果同时加入了另一个组合，只要不互斥，也校验通过
				String joinEfferObjNumber = efferObj.getObjectNumber();
				String tempEfferObjNumber = objItem.getEffectobjNumber();
				if (!joinEfferObjNumber.equals(tempEfferObjNumber)) {
					PackageObject tempEfferObj = packObjMap.get(tempEfferObjNumber);
					String tempOfferSpecId = tempEfferObj.getObjId();
					//如果产品加入的另一组合与当前组合不互斥，则校验通过
					if (!isOfferExclude(joinOfferSpecId, tempOfferSpecId)) {
						flag = true;
						break;
					}
				}
			}
		}
		return flag;
	}

	/**
	 * 是否配置了连带的销售品
	 * @param efferObj
	 * @param objItems
	 * @param packObjMap
	 * @param offerGrpMems
	 * @param isAlone
	 * @return [参数说明]
	 * 
	 */
	private boolean hasPartObjConfigedRelatedOffer(PackageObject efferObj, List<ActionOrderItem> objItems,
					Map<String, PackageObject> packObjMap, List<Map> offerGrpMems, String isAlone) {
		boolean flag = false;
		String joinEfferObjNumber = efferObj.getObjectNumber();
		if (isAlone.equals("Y")) {//如果组成员是独立的，只需组内的任意一个成员即可
			flag = false;
			outer: for (ActionOrderItem objItem : objItems) {
				String tempEfferObjNumber = objItem.getEffectobjNumber();
				if (!joinEfferObjNumber.equals(tempEfferObjNumber)) {
					PackageObject tempEfferObj = packObjMap.get(tempEfferObjNumber);
					String tempOfferSpecId = tempEfferObj.getObjId();
					for (Map offerGrpMem : offerGrpMems) {
						String offerSpecId = String.valueOf(offerGrpMem.get("offerSpecId"));
						if (tempOfferSpecId.equals(offerSpecId)) {
							flag = true;
							break outer;
						}
					}
				}
			}
		} else if (isAlone.equals("N")) {//如果组成员不是独立的，则需组内的所有成员
			flag = true;
			for (Map offerGrpMem : offerGrpMems) {
				String offerSpecId = String.valueOf(offerGrpMem.get("offerSpecId"));
				boolean offerFlag = false;
				for (ActionOrderItem objItem : objItems) {
					String tempEfferObjNumber = objItem.getEffectobjNumber();
					if (!joinEfferObjNumber.equals(tempEfferObjNumber)) {
						PackageObject tempEfferObj = packObjMap.get(tempEfferObjNumber);
						String tempOfferSpecId = tempEfferObj.getObjId();
						if (tempOfferSpecId.equals(offerSpecId)) {
							offerFlag = true;
							break;
						}
					}
				}
				if (!offerFlag) {
					flag = false;
					break;
				}
			}
		}

		return flag;
	}

	/**
	 * 参与对象相关的目标对象
	 * @param objItems
	 * @param packObjMap
	 * @return [参数说明]
	 */
	private List<PackageObject> getPartRelaEffectObjs(List<ActionOrderItem> objItems,
					Map<String, PackageObject> packObjMap) {
		List<PackageObject> partRelaEffectObjs = new ArrayList<PackageObject>();
		for (ActionOrderItem objItem : objItems) {
			String effectNumber = objItem.getEffectobjNumber();
			PackageObject effectObj = packObjMap.get(effectNumber);
			if (!partRelaEffectObjs.contains(effectObj)) {
				partRelaEffectObjs.add(effectObj);
			}
		}
		return partRelaEffectObjs;
	}

	//校验参与对象的是否有多次订购或多次加入的动作
	private CheckResult checkRelaOfferAmount(List<ActionOrderItem> objItems, Map<String, PackageObject> packObjMap) {
		CheckResult checkResult = new CheckResult(true);
		StringBuffer errMsg = new StringBuffer();
		StringBuffer promptMsg = new StringBuffer();

		//不能订购多个主销售品
		CheckResult ifOrderMultiCore = ifHasOrderMultiCoreOffer(objItems, packObjMap);
		if (!ifOrderMultiCore.isResult()) {
			checkResult.setResult(false);
			errMsg.append(ifOrderMultiCore.getErrMsg());
		}
		//不能加入或订购了多个相同的销售品
		CheckResult ifJoinSameOffer = ifHasSameCompOffer(objItems, packObjMap);
		if (!ifJoinSameOffer.isResult()) {
			checkResult.setResult(false);
			errMsg.append(ifJoinSameOffer.getErrMsg());
		}

		checkResult.setErrMsg(errMsg.toString());
		checkResult.setPromptMsg(promptMsg.toString());
		return checkResult;
	}

	//校验加入动作是否配置了相应的订购动作（如果需要配置）
	private CheckResult checkHasConfigedReqOffer(ActionOrderItem currItem, List<ActionOrderItem> objItems,
					List<ActionOrderItem> packActionItems, Map<String, PackageObject> packObjMap) {
		CheckResult checkResult = new CheckResult(true);
		StringBuffer errMsg = new StringBuffer();
		StringBuffer promptMsg = new StringBuffer();

		List<String> errMsgs = new ArrayList<String>();
		//根据目标对象查询加入的参与对象是否配置了基础
		String partObjNumber = currItem.getPartobjNumber();
		String effectObjNumber = currItem.getEffectobjNumber();
		PackageObject partObject = packObjMap.get(partObjNumber);
		PackageObject efferObject = packObjMap.get(effectObjNumber);
		String partObjType = partObject.getObjType();
		String partObjId = partObject.getObjId();
		String offerSpecId = efferObject.getObjId();
		String roleCd = currItem.getRoleCd();
		//获取加入销售品的付费方式
		String feeType = getEffectObjFeeType(effectObjNumber, packActionItems, packObjMap);

		Map<String, Object> params = new HashMap<String, Object>();
		params.put("offerSpecId", offerSpecId);
		params.put("roleCd", roleCd);
		//获取同预同后的成员
		String key = offerSpecId + "_" + roleCd;
		List<RoleObj> roleObjs = roleObjCache.get(key);
		if (null == roleObjs) {
			roleObjs = packageObjDAO.getSameFeeTypeRoleListByOfferSpecId(params);
			roleObjCache.put(key, roleObjs);
		}
		if (null != roleObjs && roleObjs.size() > 0) {
			for (RoleObj roleObj : roleObjs) {
				String objId = String.valueOf(roleObj.getObjId());
				String objType = String.valueOf(roleObj.getObjType());
				if (partObjType.equals(objType) && partObjId.equals(objId)) {
					params.put("offerRoleId", roleObj.getOfferRoleId());
					params.put("objType", objType);
					params.put("objId", objId);
					//成员是否配置了基础
					boolean ifHasBaseOfferCfg = packageObjDAO.ifHasBaseOfferCfg(params);
					//如果成员没有配置基础销售品，则需要为其指定一个
					if (!ifHasBaseOfferCfg) {
						//查询成员可选的销售品
						List<OfferSpecDto> coreOfferInfo = packageObjDAO.queryCoreOfferByObj(params);
						//如果组合下要求的成员销售品没配置，提示需要配置
						if (!hasPartObjConfigedCoreOffer(efferObject, objItems, packObjMap, coreOfferInfo, feeType)) {
							checkResult.setResult(false);
							if (!errMsgs.contains(efferObject.getObjectName())) {
								errMsg.append("目标对象【");
								errMsg.append(efferObject.getObjectName());
								errMsg.append("】下的【");
								errMsg.append(roleObj.getRoleName());
								errMsg.append("】需要指定一个成员销售品，请为其订购一个！");
								errMsg.append("如果已订购，请检查销售品及其付费方式是否符合要求！\n");
								errMsgs.add(efferObject.getObjectName());
							}
						}
					}
				}
			}
		}
		if (checkResult.isResult()) {
			//TODO 如果组合下的成员有依赖关系，则判断必须配置依赖的销售品
			Map<String, Object> newParams = new HashMap<String, Object>();
			newParams.put("offerSpecId", offerSpecId);
			newParams.put("roleCd", roleCd);
			List<Map> offerMemRelaGrps = packageObjDAO.getOfferMemRelaGrps(newParams);
			if (null != offerMemRelaGrps && offerMemRelaGrps.size() > 0) {
				Map offerMemRelaGrp = offerMemRelaGrps.get(0);
				String relaGrpId = String.valueOf(offerMemRelaGrp.get("relaGrpId"));
				String isAlone = String.valueOf(offerMemRelaGrp.get("isAlone"));
				String offerRoleName = String.valueOf(offerMemRelaGrp.get("offerRoleName"));
				List<Map> offerGrpMems = packageObjDAO.getOfferGrpMemsByGrpId(relaGrpId);
				if (null != offerGrpMems && offerGrpMems.size() > 0) {
					boolean hasPartObjConfigedRelatedOffer = hasPartObjConfigedRelatedOffer(efferObject, objItems,
									packObjMap, offerGrpMems, isAlone);
					if (isAlone.equals("Y") && !hasPartObjConfigedRelatedOffer) {//组内成员独立，依赖其中任何一个即可
						checkResult.setResult(false);
						if (!errMsgs.contains(efferObject.getObjectName())) {
							errMsg.append("目标对象【");
							errMsg.append(efferObject.getObjectName());
							errMsg.append("】中的【");
							errMsg.append(offerRoleName);
							errMsg.append("】上的销售品只能是[");
							for (Map offerGrpMem : offerGrpMems) {
								String offerSpecName = String.valueOf(offerGrpMem.get("offerSpecName"));
								errMsg.append(offerSpecName);
								errMsg.append(",");
							}
							errMsg.append("]中的一种！\n");
							errMsgs.add(efferObject.getObjectName());
						}
					} else if (isAlone.equals("N") && !hasPartObjConfigedRelatedOffer) {//组内成员不独立，需要依赖组中的所有成员
						checkResult.setResult(false);
						if (!errMsgs.contains(efferObject.getObjectName())) {
							errMsg.append("目标对象【");
							errMsg.append(efferObject.getObjectName());
							errMsg.append("】中的【");
							errMsg.append(offerRoleName);
							errMsg.append("】必须订购[");
							for (Map offerGrpMem : offerGrpMems) {
								String offerSpecName = String.valueOf(offerGrpMem.get("offerSpecName"));
								errMsg.append(offerSpecName);
								errMsg.append(",");
							}
							errMsg.append("]中的所有销售品！\n");
							errMsgs.add(efferObject.getObjectName());
						}
					}
				}
			}
		}
		checkResult.setErrMsg(errMsg.toString());
		checkResult.setPromptMsg(promptMsg.toString());
		return checkResult;
	}

	private boolean ifOfferIsMainOffer(String offerSpecId) {
		return packageObjDAO.ifOfferIsMainOffer(offerSpecId);
	}

	//是否订购了多个主销售品
	private CheckResult ifHasOrderMultiCoreOffer(List<ActionOrderItem> objItems, Map<String, PackageObject> packObjMap) {
		CheckResult checkResult = new CheckResult(true);
		StringBuffer errMsg = new StringBuffer();
		int count = 0;
		for (ActionOrderItem objItem : objItems) {
			String actionTypeCd = objItem.getActionTypeCd();
			if (actionTypeCd.equals(Constant.ACTION_TYPE_ORDER)) {
				String effectObjNumber = objItem.getEffectobjNumber();
				PackageObject effectObj = packObjMap.get(effectObjNumber);
				String offerSpecId = effectObj.getObjId();
				if (ifOfferIsMainOffer(offerSpecId)) {
					count++;
				}
				if (count >= 2) {
					String partObjNumber = objItem.getPartobjNumber();
					PackageObject partObj = packObjMap.get(partObjNumber);
					checkResult.setResult(false);
					errMsg.append("参与对象【");
					errMsg.append(partObj.getObjectName());
					errMsg.append("】订购了多个主销售品，请删除多余的！\n");
					break;
				}
			}
		}
		checkResult.setErrMsg(errMsg.toString());
		return checkResult;
	}

	private boolean ifHasSameOffer(ActionOrderItem currItem, List<ActionOrderItem> objItems) {
		boolean flag = false;
		String partObjNumber = currItem.getPartobjNumber();
		String efferObjNumber = currItem.getEffectobjNumber();
		for (ActionOrderItem objItem : objItems) {
			if (!currItem.getActionItemId().equals(objItem.getActionItemId())) {
				String temPartObjNumber = objItem.getPartobjNumber();
				String tempEfferObjNumber = objItem.getEffectobjNumber();
				if (partObjNumber.equals(temPartObjNumber) && efferObjNumber.equals(tempEfferObjNumber)) {
					flag = true;
					break;
				}
			}
		}
		return flag;
	}

	//是否有多个相同的销售品
	private CheckResult ifHasSameCompOffer(List<ActionOrderItem> objItems, Map<String, PackageObject> packObjMap) {
		CheckResult checkResult = new CheckResult(true);
		StringBuffer errMsg = new StringBuffer();
		List<String> errMsgList = new ArrayList<String>();
		for (ActionOrderItem objItem : objItems) {
			String actionTypeCd = objItem.getActionTypeCd();
			if (actionTypeCd.equals(Constant.ACTION_TYPE_ORDER)) {
				if (!errMsgList.contains(Constant.ACTION_TYPE_ORDER)) {
					if (ifHasSameOffer(objItem, objItems)) {
						String partObjNumber = objItem.getPartobjNumber();
						PackageObject partObj = packObjMap.get(partObjNumber);
						checkResult.setResult(false);
						errMsg.append("参与对象【");
						errMsg.append(partObj.getObjectName());
						errMsg.append("】订购了多个相同的销售品，请删除多余的！\n");
						errMsgList.add(Constant.ACTION_TYPE_ORDER);
					}

				}
			} else if (actionTypeCd.equals(Constant.ACTION_TYPE_JOIN)) {
				if (!errMsgList.contains(Constant.ACTION_TYPE_JOIN)) {
					if (ifHasSameOffer(objItem, objItems)) {
						String partObjNumber = objItem.getPartobjNumber();
						PackageObject partObj = packObjMap.get(partObjNumber);
						checkResult.setResult(false);
						errMsg.append("参与对象【");
						errMsg.append(partObj.getObjectName());
						errMsg.append("】加入了多个相同的销售品，请删除多余的！\n");
						errMsgList.add(Constant.ACTION_TYPE_JOIN);
					}
				}
			}
		}

		checkResult.setErrMsg(errMsg.toString());
		return checkResult;
	}

	/**
	 * 校验连带销售品
	 * @param currJoinItem
	 * @param objItems
	 * @param packObjMap
	 * @return [参数说明]
	 * 
	 */
	public CheckResult checkRelatedOffer(ActionOrderItem currItem, List<ActionOrderItem> objItems,
					Map<String, PackageObject> packObjMap) {
		CheckResult checkResult = new CheckResult(true);
		StringBuffer errMsg = new StringBuffer();
		String orderEfferNumber = currItem.getEffectobjNumber();
		PackageObject orderEffectObj = packObjMap.get(orderEfferNumber);
		String offerSpecId = orderEffectObj.getObjId();
		String key = "related_" + offerSpecId;
		List<String> relatedOffers = offerSpecCache.get(key);
		if (relatedOffers == null) {
			//查询连带销售品规格
			relatedOffers = packageObjDAO.queryRelatedOffers(offerSpecId);
			offerSpecCache.put(key, relatedOffers);
		}
		for (ActionOrderItem actionOrderItem : objItems) {
			String actionTypeCd = actionOrderItem.getActionTypeCd();
			//产品订购销售品时判断是否为连带
			if (actionTypeCd.equals(Constant.ACTION_TYPE_ORDER)) {
				String effectObjNumber = actionOrderItem.getEffectobjNumber();

				if (relatedOffers != null) {
					PackageObject effectObj = packObjMap.get(effectObjNumber);
					if (relatedOffers.contains(effectObj.getObjId())) {
						checkResult.setResult(false);
						errMsg.append("动作条目【");
						errMsg.append(actionOrderItem.getDescription());
						errMsg.append("】中,目标对象为连带销售品，请删除该条目！\n");
					}
				}
			}
		}
		checkResult.setErrMsg(errMsg.toString());
		return checkResult;
	}

	private int getActonOrderItemCount(String actionTypeCd, String roleCd, List<ActionOrderItem> actionOrderItemList) {
		int count = 0;
		List<String> partObjs = new ArrayList<String>();
		for (ActionOrderItem actionOrderItem : actionOrderItemList) {
			String tempActionTypeCd = actionOrderItem.getActionTypeCd();
			String tempRoleCd = actionOrderItem.getRoleCd();
			if (actionTypeCd != null && actionTypeCd.equals(tempActionTypeCd) && roleCd != null
							&& roleCd.equals(tempRoleCd)) {
				String partObjNumber = actionOrderItem.getPartobjNumber();
				if (!partObjs.contains(partObjNumber)) {
					partObjs.add(partObjNumber);
					count++;
				}
			}
		}
		return count;
	}

	//是否包含最小的成员数
	private boolean hasMinQtyRoleMember(String offerSpecId, String roleCd, int minQty,
					List<ActionOrderItem> packActionItemList, Map<String, PackageObject> packObjMap) {
		boolean flag = false;
		int count = 0;
		for (ActionOrderItem packActionItem : packActionItemList) {
			String actionTypeCd = packActionItem.getActionTypeCd();
			if (actionTypeCd.equals(Constant.ACTION_TYPE_JOIN)) {
				String effectObjNumber = packActionItem.getEffectobjNumber();
				PackageObject efferObj = packObjMap.get(effectObjNumber);
				String tempOfferSpecId = efferObj.getObjId();
				String temproleCd = packActionItem.getRoleCd();
				if (tempOfferSpecId.equals(offerSpecId) && temproleCd.equals(roleCd)) {
					count++;
				}
			}
			if (count >= minQty) {
				flag = true;
				break;
			}
		}
		return flag;
	}

	public CheckResult checkOfferMemberQty(PackageObject effectObj, List<ActionOrderItem> packActionItemList,
					Map<String, PackageObject> packObjMap) {
		CheckResult checkResult = new CheckResult(true);
		StringBuffer errMsg = new StringBuffer();
		List<String> errMsgList = new ArrayList<String>();
		String offerSpecId = effectObj.getObjId();
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("offerSpecId", offerSpecId);
		//查询加入的角色对象
		List<OfferRoles> offerRoles = offerRolesCache.get(offerSpecId);
		if (null == offerRoles) {
			offerRoles = packageObjDAO.queryOfferRoles(params);
			offerRolesCache.put(offerSpecId, offerRoles);
		}
		if (null != offerRoles && offerRoles.size() > 0) {
			for (OfferRoles offerRole : offerRoles) {
				//是否配置了要求的最小数量
				Short minQty = offerRole.getMinQty();
				Integer roleCd = offerRole.getRoleCd();
				if (minQty.intValue() >= 1) {
					boolean hasMinQtyRoleMember = hasMinQtyRoleMember(offerSpecId, String.valueOf(roleCd), minQty
									.intValue(), packActionItemList, packObjMap);
					if (!hasMinQtyRoleMember) {
						if (!errMsgList.contains(offerRole.getName())) {
							checkResult.setResult(false);
							errMsg.append("目标对象【");
							errMsg.append(effectObj.getObjectName());
							errMsg.append("】的【");
							errMsg.append(offerRole.getName());
							errMsg.append("】成员数量小于要求的最小数量，请添加！\n");
							errMsgList.add(offerRole.getName());
						}
					}
				}
			}
		}
		checkResult.setErrMsg(errMsg.toString());
		return checkResult;
	}

	/**
	 * 校验成员数量
	 * @param packActionItemList
	 * @param packObjMap
	 * @return [参数说明]
	 * 
	 */
	public CheckResult checkPackMemberQty(List<ActionOrderItem> packActionItemList,
					Map<String, PackageObject> packObjMap) {
		CheckResult checkResult = new CheckResult(true);
		StringBuffer errMsg = new StringBuffer();
		List<String> errMsgList = new ArrayList<String>();

		List<String> roleCds = new ArrayList<String>();
		for (ActionOrderItem actionOrderItem : packActionItemList) {
			String actionTypeCd = actionOrderItem.getActionTypeCd();
			//只有加入时才判断
			if (actionTypeCd.equals(Constant.ACTION_TYPE_JOIN)) {
				String partObjNumber = actionOrderItem.getPartobjNumber();
				String effectObjNumber = actionOrderItem.getEffectobjNumber();
				PackageObject effectObj = packObjMap.get(effectObjNumber);
				String offerSpecId = effectObj.getObjId();
				String roleCd = actionOrderItem.getRoleCd();
				Map<String, Object> params = new HashMap<String, Object>();
				params.put("offerSpecId", offerSpecId);
				params.put("roleCd", roleCd);
				//查询加入的角色对象
				String key = offerSpecId + "_" + roleCd;
				List<OfferRoles> offerRoles = offerRolesCache.get(key);
				if (null == offerRoles) {
					offerRoles = packageObjDAO.queryOfferRoles(params);
					offerRolesCache.put(key, offerRoles);
				}
				if (null != offerRoles && offerRoles.size() > 0) {
					OfferRoles offerRole = offerRoles.get(0);
					//最小数量为1时，参与对象不能为不需要
					Short minQty = offerRole.getMinQty();
					if (minQty.intValue() >= 1) {
						PackageObject partObj = packObjMap.get(partObjNumber);
						if (partObj.getIsNew() != null && partObj.getIsNew().indexOf("D") != -1) {
							checkResult.setResult(false);
							if (!errMsgList.contains(partObjNumber)) {
								errMsg.append("参与对象【");
								errMsg.append(partObj.getObjectName());
								errMsg.append("】不能配置不需要！\n");
								errMsgList.add(partObjNumber);
							}
						}
					}

					//角色对应的条目数量不能大于最大数量
					Short maxQty = offerRole.getMaxQty();
					//				params.put("packageId", actionOrderItem.getPackageId());
					//				params.put("actionTypeCd", Constant.ACTION_TYPE_OFFER);
					//				Long count = packageObjDAO.queryActonOrderItemCount(params);
					int count = getActonOrderItemCount(Constant.ACTION_TYPE_JOIN, actionOrderItem.getRoleCd(),
									packActionItemList);
					if (count > maxQty.intValue()) {
						checkResult.setResult(false);
						if (!roleCds.contains(roleCd)) {
							errMsg.append("目标对象【");
							errMsg.append(effectObj.getObjectName());
							errMsg.append("】对应的销售品下的【");
							errMsg.append(offerRole.getName());
							errMsg.append("】成员数量配置了");
							errMsg.append(count);
							errMsg.append("个,大于套餐要求的最大个数：");
							errMsg.append(maxQty);
							errMsg.append("个！\n");
							roleCds.add(roleCd);
						}

					}
				}
			}
		}
		checkResult.setErrMsg(errMsg.toString());
		return checkResult;
	}

	private int getRelaObjCount(String relaOfferSpecId, List<PackageObject> relaPackObjs) {
		int count = 0;
		for (PackageObject relaPackObj : relaPackObjs) {
			String objId = relaPackObj.getObjId();
			if (relaOfferSpecId.equals(objId)) {
				count++;
			}
		}
		return count;
	}

	/**
	 * 校验依赖
	 * @param objItems
	 * @param packObjMap
	 * @return [参数说明]
	 * 
	 */
	public CheckResult checkPackObjRela(ActionOrderItem objOrderItem, List<PackageObject> partRelaEffectObjs,
					Map<String, PackageObject> packObjMap) {
		CheckResult checkResult = new CheckResult(true);
		StringBuffer errMsg = new StringBuffer();
		String effectObjNumber = objOrderItem.getEffectobjNumber();
		PackageObject effectObj = packObjMap.get(effectObjNumber);
		if (effectObj.getObjType().equals(Constant.OFFER.toString())) {
			String offerSpecId = effectObj.getObjId();
			//查出所有依赖销售品(必选)
			List<Map<String, String>> relaOffers = packageObjDAO.queryOfferRelaInfo(offerSpecId);
			if (null != relaOffers && relaOffers.size() > 0) {
				for (Map<String, String> relaOffer : relaOffers) {
					String relaOfferSpecId = relaOffer.get("offerSpecId");
					String relaOfferSpecName = relaOffer.get("offerSpecName");
					int count = getRelaObjCount(relaOfferSpecId, partRelaEffectObjs);
					if (count < 1) {
						checkResult.setResult(false);
						errMsg.append("包对象【");
						errMsg.append(effectObj.getObjectName());
						errMsg.append("】依赖的销售品【");
						errMsg.append(relaOfferSpecName);
						errMsg.append("】未配置，请添加此配置！\n");
					}
				}
			}
			//查出所有依赖销售品(多选一)
			List<Map<String, String>> relaSelectOffers = packageObjDAO.querySelectOfferRelaInfo(offerSpecId);
			if (null != relaSelectOffers && relaSelectOffers.size() > 0) {
				boolean flag = false;
				StringBuffer offerNames = new StringBuffer();
				for (Map<String, String> relaOffer : relaSelectOffers) {
					String relaOfferSpecId = relaOffer.get("offerSpecId");
					String relaOfferSpecName = relaOffer.get("offerSpecName");
					offerNames.append("【");
					offerNames.append(relaOfferSpecName);
					offerNames.append("】");
					int count = getRelaObjCount(relaOfferSpecId, partRelaEffectObjs);
					if (count >= 1) {
						flag = true;
						break;
					}
				}
				if (!flag) {
					checkResult.setResult(false);
					errMsg.append("包对象【");
					errMsg.append(effectObj.getObjectName());
					errMsg.append("】 必须配置如下依赖销售品：");
					errMsg.append(offerNames);
					errMsg.append("中的一个，请添加此配置\n");
				}
			}
		}
		checkResult.setErrMsg(errMsg.toString());
		return checkResult;
	}

	/**
	 * 校验互斥
	 * @param packObjs
	 * @return [参数说明]
	 * 
	 */
	public CheckResult checkPackObjExclusive(List<PackageObject> packObjs) {
		CheckResult checkResult = new CheckResult(true);
		StringBuffer errMsg = new StringBuffer();
		for (PackageObject packObj : packObjs) {
			if (packObj.getObjType().equals(Constant.OFFER.toString())) {
				String objNumber = packObj.getObjectNumber();
				String offerSpecId = packObj.getObjId();
				String key = "exclude_" + offerSpecId;
				List<String> excludeOffers = offerSpecCache.get(key);
				if (null == excludeOffers) {
					excludeOffers = packageObjDAO.queryOfferExcludeInfo(offerSpecId);
					offerSpecCache.put(key, excludeOffers);
				}
				if (excludeOffers.size() > 0) {
					//遍历包对象，看是否存在互斥的
					for (PackageObject obj : packObjs) {
						String objId = obj.getObjId();
						if (!offerSpecId.equals(objId) && excludeOffers.contains(objId)) {
							checkResult.setResult(false);
							//如果已经提示过就不再提示，避免重复
							if (!exclusiveObjs.contains(objNumber)) {
								List<String> exclusiveList = exclusiveMap.get(objNumber);
								if (exclusiveList == null) {
									exclusiveList = new ArrayList<String>();
								}
								if (!exclusiveList.contains(obj.getObjectNumber())) {
									errMsg.append("目标对象【");
									errMsg.append(packObj.getObjectName());
									errMsg.append("】与【");
									errMsg.append(obj.getObjectName());
									errMsg.append("】互斥！\n");

									exclusiveObjs.add(objNumber);
									exclusiveList.add(objNumber);
									exclusiveMap.put(obj.getObjectNumber(), exclusiveList);
								}
								break;
							}
						}
					}
				}
			}
		}
		checkResult.setErrMsg(errMsg.toString());
		return checkResult;
	}

	public CheckResult checkPackObjAvailable(PackageObject packObj) {
		CheckResult checkResult = new CheckResult(true);
		StringBuffer errMsg = new StringBuffer();
		String objType = packObj.getObjType();
		if (!objType.equals(Constant.CUST.toString())) {
			Map<String, Object> params = new HashMap<String, Object>();
			Long count = 1L;
			if (objType.equals(Constant.PRODUCT.toString())) {
				params.put("prodSpecId", packObj.getObjId());
				count = packageObjDAO.queryAvailableProdObjCount(params);
			} else if (objType.equals(Constant.OFFER.toString())) {
				params.put("offerSpecId", packObj.getObjId());
				count = packageObjDAO.queryAvailableOfferObjCount(params);
			}

			if (count.longValue() < 1) {
				checkResult.setResult(false);
				errMsg.append("包对象【");
				errMsg.append(packObj.getObjectName());
				errMsg.append("】无效！\n");
			}
		}
		checkResult.setErrMsg(errMsg.toString());
		return checkResult;
	}

	public static void main(String[] args) {
		String feeType = "2";
		String[] values = feeType.split("\\|");
		for (int i = 0; i < values.length; i++) {
			System.out.println(values[i]);
		}
	}

}